{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "05ba1245",
   "metadata": {},
   "source": [
    "reshape和resize方法，两个方法都是用来修改数组形状的，但是有一些不同。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "81aacce0",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "74c46523",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[3 5 5 7]\n",
      " [9 7 9 3]\n",
      " [6 5 5 0]]\n",
      "[[3 5 5 7]\n",
      " [9 7 9 3]\n",
      " [6 5 5 0]]\n",
      "[[3 5 5 7 9 7]\n",
      " [9 3 6 5 5 0]]\n"
     ]
    }
   ],
   "source": [
    "# 1.reshape是将数组转换成指定的形状，然后返回转换后的结果\n",
    "# 对于原数组的形状是不会发生改变的\n",
    "a1 = np.random.randint(0,10,size=(3,4))\n",
    "print(a1)\n",
    "a2 = a1.reshape((2,6))\n",
    "print(a1)\n",
    "print(a2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "de951d7d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 3 3 1]\n",
      " [1 2 8 3]\n",
      " [6 7 9 8]]\n",
      "[[1 3 3 1 1 2]\n",
      " [8 3 6 7 9 8]]\n",
      "None\n"
     ]
    }
   ],
   "source": [
    "# resize是将数组转换成指定的形状，会直接修改数组本身，并不会返回任何值\n",
    "a1 = np.random.randint(0,10,size=(3,4))\n",
    "print(a1)\n",
    "a2 = a1.resize((2,6))\n",
    "print(a1)\n",
    "print(a2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b759fb64",
   "metadata": {},
   "source": [
    "flatten和ravel方法都是将多维数组转换为一维数组，但是有以下不同"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "e6da95a9",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[8 3 6 1]\n",
      " [8 6 9 7]\n",
      " [6 6 2 0]]\n",
      "[8 3 6 1 8 6 9 7 6 6 2 0]\n",
      "[[8 3 6 1]\n",
      " [8 6 9 7]\n",
      " [6 6 2 0]]\n"
     ]
    }
   ],
   "source": [
    "# 1.flatten是将数组转换为一维数组后，然后将这个拷贝返回去\n",
    "# 所以后续对这个返回值进行修改不会影响之前的数组\n",
    "a1 = np.random.randint(0,10,size=(3,4))\n",
    "print(a1)\n",
    "a2 = a1.flatten()\n",
    "print(a2)\n",
    "print(a1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "0860640d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "8\n"
     ]
    }
   ],
   "source": [
    "a2[0] = 88\n",
    "print(a1[0,0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "dddf25c0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "88\n"
     ]
    }
   ],
   "source": [
    "# 2.ravel是将数组转换为一维数组后，将这个视图（可以理解为引用）返回回去\n",
    "# 所以后续对这个返回值进行修改会影响之前的数组\n",
    "a3 = a1.ravel()\n",
    "a3[0] = 88\n",
    "print(a1[0,0])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "792e5a58",
   "metadata": {},
   "source": [
    "##### 如果有多个数组想要组合在一起，也可以通过其中的一些函数来实现"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "63f41b26",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[8 5 7 5 8]\n",
      " [3 7 0 3 2]\n",
      " [8 7 2 7 8]]\n",
      "[[0 1 6 0 9]]\n",
      "[[8 5 7 5 8]\n",
      " [3 7 0 3 2]\n",
      " [8 7 2 7 8]\n",
      " [0 1 6 0 9]]\n"
     ]
    }
   ],
   "source": [
    "# vstack:将数组按垂直方向进行叠加。数组的列数必须相同才能叠加。\n",
    "a1 = np.random.randint(0,10,size=(3,5))\n",
    "a2 = np.random.randint(0,10,size=(1,5))\n",
    "a3 = np.vstack([a1,a2])\n",
    "print(a1)\n",
    "print(a2)\n",
    "print(a3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "fe37c859",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0 9]\n",
      " [9 6]\n",
      " [8 0]]\n",
      "[[2]\n",
      " [6]\n",
      " [1]]\n",
      "[[0 9 2]\n",
      " [9 6 6]\n",
      " [8 0 1]]\n"
     ]
    }
   ],
   "source": [
    "# hstack:将数组按水平方向进行叠加。数组的行必须相同才能叠加。\n",
    "a1 = np.random.randint(0,10,size=(3,2))\n",
    "a2 = np.random.randint(0,10,size=(3,1))\n",
    "a3 = np.hstack([a1,a2])\n",
    "print(a1)\n",
    "print(a2)\n",
    "print(a3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "40b5d012",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1, 2, 3, 4, 5, 6])"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# concatenate([],axis):将两个数组进行叠加，但是具体是按水平方向还是按垂直方向要看axis的参数\n",
    "# 如果axis=0，那么代表的是往垂直方向叠加；如果axis=1，那么代表的是往水平方向上叠加\n",
    "# 如果axis=None，那么将会两个数组组合成一个一维数组。需要注意的是如果往水平方向上叠加，那么行数必须相同\n",
    "# 如果是往垂直方向叠加，那么列必须相同\n",
    "a = np.array([[1,2],[3,4]])\n",
    "b = np.array([[5,6]])\n",
    "np.concatenate((a,b),axis=0)\n",
    "np.concatenate((a,b.T),axis=1)\n",
    "np.concatenate((a,b),axis=None)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "082efd3b",
   "metadata": {},
   "source": [
    "### 数组的切割"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "825cecc8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[3 1 9 5]\n",
      " [0 7 7 5]\n",
      " [6 2 9 2]]\n"
     ]
    }
   ],
   "source": [
    "# hsplit：按照水平方向进行切割。\n",
    "# 用于指定分割成几列，可以使用数字来代表分成几部分，也可以使用数组来代表分割的地方。\n",
    "hs1 = np.random.randint(0,10,size=(3,4))\n",
    "print(hs1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "af85f48b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[array([[3, 1],\n",
       "        [0, 7],\n",
       "        [6, 2]]),\n",
       " array([[9, 5],\n",
       "        [7, 5],\n",
       "        [9, 2]])]"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.hsplit(hs1,2)#分割成两部分"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "cc450954",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[array([[3],\n",
       "        [0],\n",
       "        [6]]),\n",
       " array([[1],\n",
       "        [7],\n",
       "        [2]]),\n",
       " array([[9, 5],\n",
       "        [7, 5],\n",
       "        [9, 2]])]"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.hsplit(hs1,[1,2]) #代表在下标为1的地方切一刀，下标为2的地方切一刀，分成三部分"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "d61ebe82",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[8 6 3 9 9]\n",
      " [5 8 8 9 0]\n",
      " [2 6 5 1 7]\n",
      " [8 4 7 6 5]]\n"
     ]
    }
   ],
   "source": [
    "vs1 = np.random.randint(0,10,size=(4,5))\n",
    "print(vs1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "5fd68143",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[array([[8, 6, 3, 9, 9]]),\n",
       " array([[5, 8, 8, 9, 0]]),\n",
       " array([[2, 6, 5, 1, 7]]),\n",
       " array([[8, 4, 7, 6, 5]])]"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# vsplit:按照垂直方向进行切割。\n",
    "# 用于指定分割成几行，可以使用数字来代表分成几部分，也可以使用数组来代表分割的地方。\n",
    "np.vsplit(vs1,4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "e2e1f3c9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[array([[8, 6, 3, 9, 9]]),\n",
       " array([[5, 8, 8, 9, 0],\n",
       "        [2, 6, 5, 1, 7]]),\n",
       " array([[8, 4, 7, 6, 5]])]"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.vsplit(vs1,[1,3])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "ab18e7ee",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[3 1 9 5]\n",
      " [0 7 7 5]\n",
      " [6 2 9 2]]\n",
      "[array([[3],\n",
      "       [0],\n",
      "       [6]]), array([[1],\n",
      "       [7],\n",
      "       [2]]), array([[9],\n",
      "       [7],\n",
      "       [9]]), array([[5],\n",
      "       [5],\n",
      "       [2]])]\n",
      "[[8 6 3 9 9]\n",
      " [5 8 8 9 0]\n",
      " [2 6 5 1 7]\n",
      " [8 4 7 6 5]]\n",
      "[array([[8, 6, 3, 9, 9]]), array([[5, 8, 8, 9, 0]]), array([[2, 6, 5, 1, 7]]), array([[8, 4, 7, 6, 5]])]\n"
     ]
    }
   ],
   "source": [
    "# split/array_split(array,indicate_or_seciont,axis):用于指定切割方式，在切割的时候需要指定的是按照行还是列\n",
    "# axis=1代表按照列，axis=0代表按照行\n",
    "print(hs1)\n",
    "print(np.split(hs1,4,axis=1))\n",
    "print(vs1)\n",
    "print(np.split(vs1,4,axis=0))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c358f06b",
   "metadata": {},
   "source": [
    "## 数组（矩阵）转置和轴对换"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "9bed5855",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 0  1  2  3  4  5]\n",
      " [ 6  7  8  9 10 11]\n",
      " [12 13 14 15 16 17]\n",
      " [18 19 20 21 22 23]]\n",
      "[[ 0  6 12 18]\n",
      " [ 1  7 13 19]\n",
      " [ 2  8 14 20]\n",
      " [ 3  9 15 21]\n",
      " [ 4 10 16 22]\n",
      " [ 5 11 17 23]]\n"
     ]
    }
   ],
   "source": [
    "# 可以使用ndarray的T属性返回转置的结果\n",
    "a1 = np.arange(0,24).reshape((4,6))\n",
    "print(a1)\n",
    "a2 = a1.T\n",
    "print(a2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "d7f0794e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[9 8 7 4]\n",
      " [7 8 0 2]]\n",
      "[[9 7]\n",
      " [8 8]\n",
      " [7 0]\n",
      " [4 2]]\n",
      "[[88  8  7  4]\n",
      " [88  8  0  2]]\n"
     ]
    }
   ],
   "source": [
    "# 也可以使用transpose方法，该方法返回的是一个View，即修改返回值会影响到原来数组\n",
    "a1 = np.random.randint(0,10,size=(2,4))\n",
    "print(a1)\n",
    "a2 = a1.transpose()\n",
    "print(a2)\n",
    "a2[0] = 88\n",
    "print(a1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "9c117898",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[  55  145  235  325]\n",
      " [ 145  451  757 1063]\n",
      " [ 235  757 1279 1801]\n",
      " [ 325 1063 1801 2539]]\n"
     ]
    }
   ],
   "source": [
    "# 为什么要进行矩阵转置呢，有时候在做一些计算的时候需要用到。\n",
    "# 比如做矩阵的内积的时候。就必须将矩阵进行转置后再乘以之前的矩阵：\n",
    "a1 = np.arange(0,24).reshape((4,6))\n",
    "a2 = a1.T\n",
    "print(a1.dot(a2))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fe88b6a4",
   "metadata": {},
   "source": [
    "# 数组的形状改变\n",
    "1.reshape和resize都是重新定义形状的。但是reshape不会修改数组本身，而是将修改后的结果返回回去，而resize是直接修改数组  \n",
    "2.flatten和ravel都是用来将数组边成一维数组的，并且他们都不会对原数组造成修改，但是flatten返回的是一个拷贝，所以对flatten的返回值的修改不会影响到原来数组，而ravel返回的是一个View，那么对返回值的修改会影响到原来数组的值。\n",
    "\n",
    "# 数组的叠加：\n",
    "hstack代表在水平方向叠加，如果想要叠加成功，那么他们的行必须一致。\n",
    "vstack代表在垂直方向叠加，如果想要叠加成功，那么他们的列必须一致。\n",
    "concatenate可以手动的指定axis参数具体在哪个方向叠加，如果axis=0，代表在水平方向叠加，如果axis=1，代表在垂直方向叠加，如果axis=None，那么会先进行叠加，再转换成1维数组。\n",
    "# 数组的切割:\n",
    "1.hsplit代表在水平方向切割，按列进行分割的。他的切割方式有两种，第一种就是直接指定平均切割成多少列，第二种就是指定切割的下标值。    \n",
    "2.vsplit代表在垂直方向进行切割，按行进行切割。他的切割方式跟hsplit一样。   \n",
    "3.split/array_split是手动的指定axis参数，axis=0,代表按行进行切割，axis=1，代表按列进行切割。  \n",
    "# 矩阵转置：\n",
    "1.可以通过ndarray.T的形式进行转置。  \n",
    "2.也可以通过ndarray.transpose()进行转置，这个方法返回的是一个View，所以对返回值上进行修改，会影响到原来的数组。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
